﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using WebApi.Helpers;
using WebApi.Infrastructure;
using WebApi.Model;

namespace WebApi.Controllers
{
    /// <summary>
    /// 用户信息接口
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : BaseController
    {
        public UserController(ILogger<UserController> logger) : base(logger)
        {
        }

        /// <summary>
        /// 用户登录获取token
        /// </summary>
        /// <param name="model">用户实体</param>
        /// <returns>登录用户信息</returns>
        [AllowAnonymous]
        [HttpPost("Login")]
        [ProducesResponseType(typeof(ReturnModel), StatusCodes.Status200OK)]
        [ProducesResponseType(typeof(ReturnModel), StatusCodes.Status500InternalServerError)]
        public async Task<ReturnModel> LoginAsync(Users model)
        {
            logger.LogInformation(JsonConvert.SerializeObject(model));
            ReturnModel result = new ReturnModel();
            Users user = await DbHelper.Users.GetFirstAsync(it => it.UserName == model.UserName && it.Password == model.Password);
            if (user == null)
            {
                result.Code = 401;
                result.Message = "登录失败!";
            }
            else
            {
                var claims = new[]{
                        new Claim(SystemConst.UserId,user.Id.ToString()),
                        new Claim(SystemConst.UserName,user.UserName),
                        new Claim(SystemConst.UserPower,user.UserPower.ToString()),
                        //new Claim(SystemConst.SignPictureBase64,user.SignPictureBase64),//签字图片
                        new Claim(JwtRegisteredClaimNames.Iss,AppSetting.Configuration["JwtBearer:Issuer"]),
                        new Claim(JwtRegisteredClaimNames.Aud,AppSetting.Configuration["JwtBearer:Audience"]),
                    };
                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSetting.Configuration["JwtBearer:SecretKey"]));
                var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                SecurityToken token = new JwtSecurityToken(
                    signingCredentials: creds,
                    expires: DateTime.Now.AddMinutes(30),//过期时间
                    claims: claims
                );
                result.Data = user;
                result.Count = 1;
                result.Message = "Bearer " + new JwtSecurityTokenHandler().WriteToken(token);
            }
            return result;
        }


        ///// <summary>
        ///// 用户登录
        ///// </summary>
        ///// <param name="model">用户实体</param>
        ///// <returns>登录用户信息</returns>
        //[HttpPost("Login")]
        //public async Task<ReturnModel> Login(Users model)
        //{
        //    logger.LogInformation(JsonConvert.SerializeObject(model));
        //    try
        //    {
        //        ReturnModel returnModel = new ReturnModel();
        //        Users user = await DbHelper.Users.GetFirstAsync(it => it.UserName == model.UserName && it.Password == model.Password);
        //        returnModel.Data = user;
        //        returnModel.Count = user == null ? 0 : 1;
        //        returnModel.Message = returnModel.Count == 1 ? "" : "用户名或密码不正确";
        //        return returnModel;
        //    }
        //    catch (Exception ex)
        //    {
        //        return logger.ErrorModel("用户登录", ex);
        //    }
        //}

        /// <summary>
        /// App用户登录,验证用户信息以及是否完成设备检查
        /// </summary>
        /// <param name="model">用户实体</param>
        /// <returns></returns>
        [HttpPost("AppLogin")]
        public async Task<ReturnModel> AppLogin(Users model)
        {
            logger.LogInformation(JsonConvert.SerializeObject(model));
            try
            {
                ReturnModel returnModel = new ReturnModel();
                returnModel.Count = await DbHelper.Users.CountAsync(it => it.UserName == model.UserName && it.Password == model.Password);
              //  returnModel.Message = returnModel.Count == 1 ? "" : "用户名或密码不正确";
                if (returnModel.Count == 1)
                {
                    returnModel.Message = "";
                    CheckDevice checkDevice = await DbHelper.CheckDevice.GetFirstAsync(it => it.Date == DateTime.Now.ToString("yyyy-MM-dd"));
                    if (checkDevice != null)
                    {
                        // count = await DbHelper.CheckDevice.CountAsync(it => it.IsCheck == false);
                        if (checkDevice.IsCheck == false)
                        {
                            returnModel.Message = "未维护";
                        }
                    }
                    else
                    {
                        returnModel.Message = "未维护";
                        CheckDevice check = new CheckDevice();
                        check.Date = DateTime.Now.ToString("yyyy-MM-dd");
                        check.User = model.UserName;
                        check.IsCheck = false;
                        await DbHelper.CheckDevice.InsertAsync(check);
                    }
                }
                else {
                    returnModel.Message = "用户名或密码不正确";
                }

             
                return returnModel;
            }
            catch (Exception ex)
            {
                return logger.ErrorModel("用户登录", ex);
            }
        }

        #region 集控中的人员管理
        ///// <summary>
        ///// 用户登录成功则返回数据带token
        ///// </summary>
        ///// <param name="model">用户实体</param>
        ///// <returns></returns>
        //[HttpPost("LoginGetToken")]
        //public ReturnModel LoginGetToken(Users model)
        //{
        //    logger.LogInformation(JsonConvert.SerializeObject(model));
        //    try
        //    {
        //        ReturnModel returnModel = new ReturnModel();
        //        //1.查询具体是谁
        //        var user = DbHelper.Users.GetFirst(it => it.UserName == model.UserName && it.Password == model.Password);
        //        if (user != null)
        //        {
        //            string token = "";
        //            returnModel.Count = 1;
        //            switch (user.UserPower)
        //            {
        //                case 0:
        //                    returnModel.Message = "验证通过,权限Admin";
        //                    //token = GenerateToken("Admin");
        //                    break;
        //                case 1:
        //                    //token = GenerateToken("User");
        //                    returnModel.Message = "验证通过,权限User";
        //                    break;
        //                    //case 2:
        //                    //    //后续再添加--system
        //                    //    returnModel.Message = "验证通过,权限system";
        //                    //    token = GenerateToken("system");
        //                    //    break;
        //            }
        //            //2.token绑定上
        //            returnModel.Data = token;
        //            if (token == "")
        //            {
        //                returnModel.Message = "验证通过,权限未知,生成token失败";
        //            }
        //        }
        //        else
        //        {
        //            returnModel.Count = 0;
        //            returnModel.Message = "用户名或密码不正确";
        //            returnModel.Data = "";
        //        }
        //        return returnModel;
        //    }
        //    catch (Exception ex)
        //    {
        //        return logger.ErrorModel("用户登录", ex);
        //    }
        //}

        /// <summary>
        /// 获取所有人员信息(需要带token)
        /// </summary>
        /// <param name="User">用户名</param>
        /// <returns></returns>
        [HttpPost("GetUserByParameter")]
        public ReturnModel GetUserByParameter(Users User)
        {
            ReturnModel returnModel = new ReturnModel();
            var db = DbHelper.GetDbConn();
            List<Users> lst = new List<Users>();
            if (!string.IsNullOrEmpty(User.UserName))
            {
                lst = db.Queryable<Users>().Where(it => it.UserName.Contains(User.UserName)).ToList();
            }
            else
            {
                lst = db.Queryable<Users>().ToList();
            }
            if (lst != null)
            {

                returnModel.Count = lst.Count;
                returnModel.Message = "查询用户成功";
                returnModel.Data = lst;
            }
            else
            {
                returnModel.Count = 0;
                returnModel.Message = "查询用户失败";
            }
            return returnModel;
        }

        /// <summary>
        /// 新增 用户信息(需要带token)
        /// </summary>
        /// <param name="insertObj">黑名单信息</param>
        /// <returns></returns>
        [HttpPost("AddUser")]
        public ReturnModel AddUser(Users insertObj)
        {
            try
            {
                //01 数据字段长度判断
                string msg = "";
                if (insertObj == null || insertObj.UserName == "")
                {
                    logger.LogError(msg);
                    return new ReturnModel { Code = 500, Message = "新增数据失败：数据字段不能为空。" };
                }
                //02 数据项重复判断
                var db = DbHelper.GetDbConn();
                List<Users> listResult = db.Queryable<Users>()
                    .Where(it => it.UserName == insertObj.UserName && it.UserPower == insertObj.UserPower)//in 查询
                    .ToList();
                //判断是否存在此code
                if (listResult != null && listResult.Count != 0)
                {
                    logger.LogError("UserController-->AddUser:新增数据失败");
                    string tipMsg = "新增数据失败,用户信息不能重复";
                    return new ReturnModel { Code = 500, Message = tipMsg };
                }
                //03 返回插入行数
                int iExeCount = db.Insertable(insertObj).ExecuteCommand(); //都是参数化实现                
                if (iExeCount == 1)
                {
                    return new ReturnModel();
                }
                else
                {
                    logger.LogError("UserController-->AddUser:新增数据失败");
                    return new ReturnModel { Code = 500, Message = "新增数据失败" };
                }
            }
            catch (Exception ex)
            {
                logger.LogError("UserController-->AddUser:" + ex.ToString());
                return new ReturnModel { Code = 500, Message = "系统内部错误" };
            }
        }

        /// <summary>
        /// 更新用户信息(需要带token)
        /// </summary>
        /// <param name="obj">更新实体</param>
        /// <returns></returns>
        [HttpPost("UpdataUser")]
        public ReturnModel UpdataUser(Users obj)
        {
            try
            {
                var db = DbHelper.GetDbConn();
                if (db.Queryable<Users>().Where(it => it.Id != obj.Id && it.UserName == obj.UserName && it.UserPower == obj.UserPower).Any())
                {
                    logger.LogError("UserController-->UpdataUser:更新数据失败,此数数重复");
                    return new ReturnModel { Code = 500, Message = "更新数据失败,此数数重复" };
                }
                //返回行数
                int iExeCount = db.Updateable(obj).ExecuteCommand(); //都是参数化实现                
                if (iExeCount == 1)
                {
                    return new ReturnModel();
                }
                else
                {
                    logger.LogError("UserController-->UpdataUser:更新数据失败");
                    return new ReturnModel { Code = 500, Message = "新增数据失败" };
                }
            }
            catch (Exception ex)
            {
                logger.LogError("UserController-->UpdataUser:" + ex.ToString());
                return new ReturnModel { Code = 500, Message = "系统内部错误" };
            }
        }
        /// <summary>
        /// 更新用户信息(需要带token)
        /// </summary>
        /// <param name="obj">更新实体</param>
        /// <returns></returns>
        [HttpPost("UpdataUserSign")]
        public ReturnModel UpdataUserSign(Users obj)
        {
            try
            {
                var db = DbHelper.GetDbConn();
                //返回行数
                int iExeCount = db.Updateable(obj).WhereColumns(it => new { it.Id }).UpdateColumns(it => new { it.SignPictureBase64 }).ExecuteCommand(); //都是参数化实现               

                if (iExeCount == 1)
                {
                    return new ReturnModel();
                }
                else
                {
                    logger.LogError("UserController-->UpdataUserSign:更新签字数据失败");
                    return new ReturnModel { Code = 500, Message = "新增数据失败" };
                }
            }
            catch (Exception ex)
            {
                logger.LogError("UserController-->UpdataUserSign:" + ex.ToString());
                return new ReturnModel { Code = 500, Message = "系统内部错误" };
            }
        }

        /// <summary>
        /// 删除 用户信息(需要带token)
        /// </summary>
        /// <param name="obj">实体，但只用id</param>
        /// <returns></returns>
        [HttpPost("DeleteUser")]
        public ReturnModel DeleteUser(Users obj)
        {
            try
            {
                var db = DbHelper.GetDbConn();
                var result = db.Deleteable<Users>().Where(new Users() { Id = obj.Id }).ExecuteCommand();
                string msg = "";
                if (result == 1)
                {
                    string userMsg = obj.UserPower.Equals(0) ? "管理员" : "用户";
                    msg = "UserController-->DeleteUser:删除数据成功," + "删除用户名：" + obj.UserName + " 用户权限：" + userMsg;
                    logger.LogError(msg);
                    return new ReturnModel { Code = 200, Message = "删除数据成功" };
                }
                else
                {
                    logger.LogError("UserController-->DeleteUser:删除数据失败");
                    return new ReturnModel { Code = 500, Message = "删除数据失败" };
                }
            }
            catch (Exception ex)
            {
                logger.LogError("UserController-->DeleteUser:" + ex.ToString());
                return new ReturnModel { Code = 500, Message = "删除出错" };
            }
        }

        #endregion

        /// <summary>
        /// 获取签字图片
        /// </summary>
        /// <param name="UserId">用户Id</param>
        /// <returns></returns>
        [HttpPost("GetUserSignPictureBase64ById")]
        public ReturnModel GetUserSignPictureBase64ById(int UserId)
        {
            try
            {
                var db = DbHelper.GetDbConn();
                ReturnModel result = new ReturnModel();
                Users user = DbHelper.Users.GetFirst(it => it.Id == UserId);
                if (user == null)
                {
                    result.Code = 201;
                    result.Data = "";
                    result.Message = "未查询到用户信息";
                    return result;
                }
                else
                {
                    result.Code = 200;
                    result.Data = user.SignPictureBase64;
                    result.Message = "查询成功";
                    return result;
                }
            }
            catch (Exception ex)
            {
                logger.LogError("UserController-->GetUserSignPictureBase64ById:" + ex.ToString());
                LogToDB("User", "查询", $"UserID={UserId}", "异常", ex.Message);
                return new ReturnModel { Code = 500, Message = "查询出错" };
            }
        }


        /// <summary>
        /// 获取用户列表，只提供给汽车衡使用，返回用户列表，但不包含签字图片
        /// </summary>
        /// <returns></returns>
        [HttpPost("GetList")]
        public async Task<ReturnModel> GetList()
        {
            try
            {
                var data = await DbHelper.Users.AsQueryable().IgnoreColumns(it => new {it.SignPictureBase64}).ToListAsync();
                return new ReturnModel { Count = data.Count, Data = data };
            }
            catch (Exception ex)
            {
                return logger.ErrorModel($"{nameof(UserController)}/{nameof(GetList)}", ex);
            }
        }
    }
}
